package org.openfidias.jdbase.model;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.RandomAccessFile;
import org.openfidias.jdbase.db.DbManager;
import org.openfidias.jdbase.locale.Message;
import org.openfidias.jdbase.util.Do;

/**
 *
 * @author atila
 */
public class DisciplinaDao {

   private static final String table = "disciplina.table";
   public static final String logicalTable = "Disciplina";
   private static final String deletedTable = "disciplina.deleted";

   private DisciplinaDao() {
   }

   public static DisciplinaDao getInstance() {
      return DisciplinaDaoHolder.INSTANCE;
   }

   private static class DisciplinaDaoHolder {

      private static final DisciplinaDao INSTANCE = new DisciplinaDao();
   }

   public void create(Disciplina disciplina) throws IOException, Exception {
      try {
         Do.create(disciplina, table, deletedTable);
      } catch (Exception e) {
         throw new Exception(e);
      }
   }

   /**
    * TODO: mudar retorno para void e usar propria referencia.
    * @deprecated
    * @param disciplina
    * @return
    * @throws IOException
    * @throws Exception
    */
   public Disciplina read(Disciplina disciplina) throws IOException, Exception {
      try {
         return (Disciplina) Do.read(disciplina, table);
      } catch (Exception e) {
         throw new Exception(e);
      }
   }

   public Disciplina read(int codigo) throws IOException, Exception {
      try {
         Disciplina disciplina = new Disciplina(codigo);
         return (Disciplina) Do.read(disciplina, table);
      } catch (Exception e) {
         throw new Exception(e);
      }
   }

   public boolean delete(int codigo) throws IOException, Exception {
      try {
         Disciplina tmpDisciplina = new Disciplina(codigo);
         boolean del = false;

         if (exists(codigo)) {
            File f = DbManager.getTable(table);
            RandomAccessFile file = new RandomAccessFile(f, "rw");
            long pointer = file.getFilePointer();
            String line = file.readLine();
            while (line != null) {
               Disciplina d = (Disciplina) new Disciplina().fromLine(line);
               if (tmpDisciplina.equals(d)) {
                  file.seek(pointer);
                  file.write("1".getBytes());
                  // save pointer to file deletedFile
                  DbManager.logicalDelete(deletedTable, pointer);
                  del = true;
                  line = null;
                  continue;
               }
               pointer = file.getFilePointer();
               line = file.readLine();
            }
            file.close();
            return del;
         } else {
            // not exists
            System.out.println(Message.notFound("Código"));
            return del;
         }
      } catch (IOException iOException) {
         throw new IOException(Message.tableNotFound(table));
      } catch (Exception e) {
         throw new Exception(e);
      }
   }

   public void list() throws IOException, Exception {
      try {
         File f = DbManager.getTable(table);
         BufferedReader reader = new BufferedReader(new FileReader(f));
         // print the table header.
         System.out.println(Disciplina.headerTable());
         String line = reader.readLine();
         while (line != null) {
            Disciplina disciplina = (Disciplina) new Disciplina().fromLine(line);
            if (disciplina.isNotDeleted()) {
               System.out.println(disciplina);
            }
            line = reader.readLine();
         }
         System.out.println(Disciplina.rowSeparator());
         reader.close();
      } catch (IOException iOException) {
         throw new IOException(Message.tableNotFound(table));
      } catch (Exception e) {
         throw new Exception(e);
      }
   }

   public boolean exists(int codigo) throws IOException {
      boolean exists = false;
      Disciplina d = new Disciplina(codigo);
      File f = DbManager.getTable(table);
      BufferedReader reader = new BufferedReader(new FileReader(f));
      String line = reader.readLine();
      while (line != null) {
         Disciplina disciplina = (Disciplina) new Disciplina().fromLine(line);
         if (d.equals(disciplina) && disciplina.isNotDeleted()) {
            exists = true;
            line = null;
            continue;
         }
         line = reader.readLine();
      }
      reader.close();
      return exists;
   }
}
